#ifndef __A010_H__
#define __A010_H__
#include <fcntl.h>
#include <termios.h>
#include <unistd.h>
#include <atomic>

#define STRINGIFY(x) #x
#define TOSTRING(x) STRINGIFY(x)

#define A010_UART_CHOSE "/dev/ttyS9"

#define UART_RX_MAX_QUEUE_SIZE      (256)
#define UART_RX_MAX_BUFFER_SIZE     (32768)

#define A010_VALUE_DISP_USB     2
#define A010_VALUE_DISP_UART    4
#define A010_VALUE_DISP_STOP    0

// 修改配置宏
#define A010_CONFIG_DISP_USB    "AT+DISP=" TOSTRING(A010_VALUE_DISP_USB) "\r\n"
#define A010_CONFIG_DISP_UART   "AT+DISP=" TOSTRING(A010_VALUE_DISP_UART) "\r\n"
#define A010_CONFIG_DISP_STOP   "AT+DISP=" TOSTRING(A010_VALUE_DISP_STOP) "\r\n"

#define A010_VALUE_FPS          19
#define A010_CONFIG_FPS         "AT+FPS=" TOSTRING(A010_VALUE_FPS) "\r\n"

#define A010_VALUE_UNIT         0
#define A010_CONFIG_UNIT        "AT+UNIT=" TOSTRING(A010_VALUE_UNIT) "\r\n"

#define A010_VALUE_ISP_OFF      0
#define A010_VALUE_ISP_ON       1
#define A010_CONFIG_ISP_ON      "AT+ISP=" TOSTRING(A010_VALUE_ISP_ON) "\r\n"

#define A010_VALUE_BINN_100     1
#define A010_VALUE_BINN_50      2
#define A010_VALUE_BINN_25      4
#define A010_CONFIG_BINN_100    "AT+BINN=" TOSTRING(A010_VALUE_BINN_100) "\r\n"

#define A010_CONFIG_SAVE        "AT+SAVE\r\n"
/*
*  9600      0
*  57600     1
*  115200    2
*  230400    3
*  460800    4
*  921600    5
*  1000000   6
*  2000000   7
*  3000000   8
*/
#define A010_VALUE_BAUD             8  // 对应3000000波特率
#define A010_CONFIG_BAUD            "AT+BAUD=" TOSTRING(A010_VALUE_BAUD) "\r\n"

#define A010_VALUE_BAUD_0               (B9600)
#define A010_VALUE_BAUD_1               (B57600)
#define A010_VALUE_BAUD_2               (B115200)
#define A010_VALUE_BAUD_3               (B230400)
#define A010_VALUE_BAUD_4               (B460800)
#define A010_VALUE_BAUD_5               (B921600)
#define A010_VALUE_BAUD_6               (B1000000)
#define A010_VALUE_BAUD_7               (B2000000)
#define A010_VALUE_BAUD_8               (B3000000)

#define A010_TRANS_TIME         (30)    

#define A010_FRAME_SIZE (10022)      // 4+16+10000+1+1
#define A010_PARSE_DROP (0)          // 0表示全解析，x表示解析1帧后跳过x帧 这里的跳帧判断放在帧序号检测之后 如果设置跳帧 则必定会丢失数据

/*
传感器发送数据为连续发送，而不是配置多少帧就以多少帧的频率发送。
若波特率为3000000，就算A010_CONFIG_FPS配置的是1帧，但传感器还是会连续发送数据
一秒钟依旧会接收到3000000/10/A010_FRAME_SIZE=29帧数据
如果对这些数据全部解析，那么实际上应该以29帧的速度播放才不会有卡顿。

理论FPS值计算方式：
A010_BAUD/10/A010_FRAME_SIZE/(A010_PARSE_DROP+1)
比如真实波特率为115200，A010_PARSE_DROP为0，则真实FPS大约为1
*/

#define A010_HEADER (const uint8_t[]){0x00, 0xFF, 0x20, 0x27}

/*
调试用宏定义
*/
#define A010_SAVE_WHOLE_FRAME (1)  //在解析模式下 定义是否导出完整帧到文件 否则建立成数据结构体导出

#define A010_PARSE_DEBUG_FLAG (0)  //定义是否开启解析调试功能 调试模式下不解析 而是直接将所有数据导出 为0则是解析模式 解析模式下会判断抽帧等方式

#if !(A010_PARSE_DEBUG_FLAG)
#define A010_FRAME_DEBUG_FLAG (0)  ///解析模式下 不导出文件时 解析成功时 定义是否打印帧号的debug信息
#define A010_PARSE_LOG_FLAG   (1)  //解析模式下 不导出文件时 定义是否打印log信息
#endif

typedef struct 
{
    uint8_t FPS;
    uint8_t unit;
    uint32_t baud;
    uint8_t error;
}A010_ConfigType;

typedef struct 
{
    uint32_t frameNum;
    uint8_t subFrameNum;
    uint8_t data[10000];
}A010_DataType;

int ConfigureSerial(int fd, speed_t speed);

bool A010_Send(int uart,const char* cmd);
int A010_Init(int uart);
void A010_Open(int uart);

int A010_ParseData(const uint8_t * buf,size_t len);

A010_ConfigType A010_GetConfig(void);

#endif
